﻿//-----------------------------------------------------------------------
// <copyright file="ICanvasRenderer.cs" company="Nathan Miller">
// Copyright (c) Nathan Miller.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
//-----------------------------------------------------------------------
namespace TileTool.Render
{
    using TileTool.Common.Math;

    /// <summary>
    /// Interface for the renderer which draws into a canvas.
    /// 
    /// The following properties must be saved / restored during
    /// a render state push and pop:
    ///     * AntiAlias
    /// </summary>
    public interface ICanvasRenderer
    {
        #region Properties

        /// <summary>
        /// Gets the current transform for the renderer.
        /// </summary>
        Matrix2D Transform
        {
            get;
        }

        /// <summary>
        /// Gets or sets if anti-aliasing should be used.
        /// </summary>
        bool AntiAlias
        {
            get;
            set;
        }

        #endregion

        #region Methods - Transform

        /// <summary>
        /// Push a matrix onto the transform stack.
        /// </summary>
        /// <param name="mat">Matrix to push onto the stack.</param>
        void PushMatrix(Matrix2D mat);

        /// <summary>
        /// Pop a matrix off of the transform stack.
        /// </summary>
        void PopMatrix();

        #endregion

        #region Methods - Render state

        /// <summary>
        /// Push a new render state onto the state stack.
        /// </summary>
        void PushState();

        /// <summary>
        /// Pop a render state off of the state stack.
        /// </summary>
        void PopState();

        #endregion

        #region Methods - Base rendering

        /// <summary>
        /// Clear the canvas with the passed color.
        /// </summary>
        /// <param name="color">Color to clear the canvas with.</param>
        void Clear(ColorRGBA color);

        /// <summary>
        /// Draw a line from point a to b with the passed color and line width.
        /// </summary>
        /// <param name="a">Start point.</param>
        /// <param name="b">End point.</param>
        /// <param name="color">Line color.</param>
        /// <param name="width">Line width.</param>
        void DrawLine(Vector2D a, Vector2D b, ColorRGBA color, float width);
        
        /// <summary>
        /// Draw a line rectangle.
        /// </summary>
        /// <param name="pos">Position of the rectangle.</param>
        /// <param name="size">Size of the rectangle to draw.</param>
        /// <param name="color">Color of the rectangle.</param>
        /// <param name="width">Width of the lines that make up the rectangle.</param>
        void DrawLineRect(Vector2D pos, Size2D size, ColorRGBA color, float width);

        /// <summary>
        /// Draw a filled rectangle.
        /// </summary>
        /// <param name="pos">Position of the rectangle.</param>
        /// <param name="size">Size of the rectangle to draw.</param>
        /// <param name="color">Color of the rectangle.</param>
        void DrawFilledRect(Vector2D pos, Size2D size, ColorRGBA color);

        /// <summary>
        /// Draw a line ellipse.
        /// </summary>
        /// <param name="pos">Center position of the ellipse.</param>
        /// <param name="size">Size of the ellipse.</param>
        /// <param name="color">Color of the ellipse.</param>
        /// <param name="width">Width of the lines that make up the ellipse.</param>
        void DrawLineEllipse(Vector2D pos, Size2D size, ColorRGBA color, float width);

        /// <summary>
        /// Draw a filled ellipse.
        /// </summary>
        /// <param name="pos">Center position of the ellipse.</param>
        /// <param name="size">Size of the ellipse.</param>
        /// <param name="color">Color of the ellipse.</param>
        void DrawFilledEllipse(Vector2D pos, Size2D size, ColorRGBA color);

        /// <summary>
        /// Draw a line triangle made up of the passed points.
        /// </summary>
        /// <param name="p0">Point 0.</param>
        /// <param name="p1">Point 1.</param>
        /// <param name="p2">Point 2.</param>
        /// <param name="color">Color of the triangle.</param>
        void DrawLineTriangle(Vector2D p0, Vector2D p1, Vector2D p2, ColorRGBA color);

        /// <summary>
        /// Draw a filled triangle made up of the passed points.
        /// </summary>
        /// <param name="p0">Point 0.</param>
        /// <param name="p1">Point 1.</param>
        /// <param name="p2">Point 2.</param>
        /// <param name="color">Color of the triangle.</param>
        void DrawFilledTriangle(Vector2D p0, Vector2D p1, Vector2D p2, ColorRGBA color);

        #endregion

        #region Methods - Render utility functions

        /// <summary>
        /// Draw a grid using the color values in RenderSettings.
        /// </summary>
        /// <param name="camera">Camera to use as a reference in drawing.</param>
        /// <param name="width">Width of each grid cell.</param>
        /// <param name="height">Height of each grid cell.</param>
        void DrawGrid(ICamera camera, int width, int height);

        #endregion
    }
}
